package com.ss.timetip.ctr;

import cn.hutool.core.io.IORuntimeException;
import cn.hutool.core.io.file.FileReader;
import cn.hutool.core.io.file.FileWriter;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.ss.timetip.model.Setting;
import javafx.concurrent.ScheduledService;
import javafx.concurrent.Task;
import javafx.event.ActionEvent;
import javafx.fxml.Initializable;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyCodeCombination;
import javafx.scene.input.KeyCombination;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javafx.util.Duration;

import java.io.File;
import java.net.URL;
import java.util.Date;
import java.util.ResourceBundle;
import java.util.concurrent.Executors;

public class Controller implements Initializable {
    public TextField walk;
    public TextField stand;
    public TextArea orderList;
    private int orderNum = 0;
    ScheduledService<Void> standService;
    ScheduledService<Void> walkService;

    private final String orderPath = getClass().getResource("/").toString() + File.separator + "pp/order";
    private final String settingPath = getClass().getResource("/").toString() + File.separator + "pp/setting.json";

    public void saveSetting(ActionEvent actionEvent) {
        Setting setting = new Setting();
        setting.standPeriod = Double.parseDouble(stand.getText());
        setting.walkPeriod = Double.parseDouble(walk.getText());
        setLoad(setting);
        Task<Object> saveSettingTask = new Task<>() {
            @Override
            protected Object call() {
                FileWriter reader = new FileWriter(settingPath);
                reader.write(JSONUtil.toJsonStr(setting));
                return null;
            }
        };
        new Thread(saveSettingTask).start();
    }

    public void saveOrder(ActionEvent actionEvent) {
        Task<Object> saveSettingTask = new Task<>() {
            @Override
            protected Object call() {
                FileWriter reader = new FileWriter(orderPath);
                reader.write(orderList.getText());
                return null;
            }
        };
        new Thread(saveSettingTask).start();
    }

    @Override
    public void initialize(URL url, ResourceBundle resourceBundle) {

        double standUp = 30;
        double walk = 120;


        Dialog walks = new Dialog("该活动了");
        Dialog stands = new Dialog("小憩片刻");

        this.walk.setText(walk + "");
        this.stand.setText(standUp + "");

        standService = scheduledService("没事走两步", stands, standUp);
        walkService = scheduledService("出去走走", walks, walk);

        loadSetting();
        loadOrder();

    }

    private void setLoad(Setting setting) {
        standService.setDelay(Duration.minutes(setting.standPeriod));
        walkService.setDelay(Duration.minutes(setting.walkPeriod));
        standService.setPeriod(Duration.minutes(setting.standPeriod));
        walkService.setPeriod(Duration.minutes(setting.walkPeriod));
        standService.cancel();
        walkService.cancel();
        standService.restart();
        walkService.restart();
    }

    private void loadSetting() {
        Task<Setting> task = new Task<>() {
            @Override
            protected Setting call() throws Exception {
                FileReader settingReader = new FileReader(settingPath);
                String s = settingReader.readString();
                return JSONUtil.toBean(s, Setting.class);
            }

            @Override
            protected void updateValue(Setting setting) {
                setLoad(setting);
                Controller.this.walk.setText(setting.walkPeriod + "");
                Controller.this.stand.setText(setting.standPeriod + "");
            }
        };

        new Thread(task).start();
    }

    private void loadOrder() {
        Task<String> task = new Task<>() {
            @Override
            protected String call() throws Exception {
                FileReader settingReader = new FileReader(orderPath);
                return settingReader.readString();
            }

            @Override
            protected void updateValue(String value) {
                orderList.setText(value);
            }


        };
        new Thread(task).start();
    }

    private ScheduledService<Void> scheduledService(String msg, Dialog dialog, double time) {

        ScheduledService<Void> service1 = new ScheduledService<>() {
            @Override
            protected Task<Void> createTask() {
                return new Task<>() {
                    @Override
                    protected Void call() {
                        try {
                            FileReader reader = new FileReader(orderPath);

                            String[] orderArr = reader.readString().split("\n");
                            if (orderNum < orderArr.length && StrUtil.isNotBlank(orderArr[orderNum])) {
                                dialog.msg = orderArr[orderNum++];
                            } else {
                                dialog.msg = msg;
                            }
                        } catch (IORuntimeException e) {
                            e.printStackTrace();
                        }
                        return null;
                    }
                };
            }
        };

        service1.setExecutor(Executors.newFixedThreadPool(1));
        service1.setDelay(Duration.minutes(time));
        service1.setPeriod(Duration.minutes(time));
        service1.start();

        service1.setOnSucceeded(workerStateEvent -> {
            dialog.close();
            dialog.show();
            System.out.println(new Date());
            System.out.println(dialog.msg);
        });
        return service1;
    }

    public void snrOrder(ActionEvent actionEvent) {
        saveOrder(actionEvent);
        orderNum = 0;
    }


    private static class Dialog extends Stage {
        private String msg;
        private final String title;

        public Dialog(String title) {
            this.title = title;
            init();
        }

        private void init() {
            setWidth(300);
            this.setAlwaysOnTop(true);
//        this.initModality(Modality.APPLICATION_MODAL);
            Button closeBtn = new Button("知道了");
            closeBtn.setOnAction(e -> this.close());
            VBox root = new VBox();
            root.setPadding(new Insets(20));
            root.setAlignment(Pos.BASELINE_CENTER);
            root.setSpacing(20);
            Label l = new Label();
            root.getChildren().addAll(l, closeBtn);
            Scene scene = new Scene(root);
            this.setScene(scene);
            this.setTitle(title);
            KeyCombination kc = new KeyCodeCombination(KeyCode.ESCAPE);
            scene.getAccelerators().put(kc, this::close);
            this.setOnShowing(windowEvent -> {
                l.setText(msg);
            });
        }
    }
}
